<template>
  <div id="app">
    <el-form
      ref="form"
      label-position="top"
      :rules="rules"
      :model="form"
      label-width="80px"
    >
      <el-form-item label="模板上传" prop="templateFile">
        <el-upload
          v-if="!form.templateFile"
          class="upload-demo"
          drag
          :auto-upload="false"
          :before-upload="(flie) => beforeUpload(flie, ['xlsx', 'docx'])"
          :show-file-list="false"
          :on-change="handleAvatarSuccess"
          :accept="['.xlsx', '.docx'].join(',')"
          action="https://httpbin.org/post"
        >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">
            将文件拖到此处，或<em>点击上传</em>,仅支持xlsx,docx格式
          </div>
        </el-upload>
        <Show-List v-else :item.sync="form.templateFile"> </Show-List>
      </el-form-item>
      <el-form-item v-if="options.length" label="选择页码" prop="sheetNumber">
        <el-select v-model="form.sheetNumber" placeholder="请选择">
          <el-option
            v-for="item in options"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          >
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item prop="dataFile" label="数据文件上传">
        <el-upload
          v-if="!form.dataFile"
          :auto-upload="false"
          class="upload-demo"
          drag
          :before-upload="(flie) => beforeUpload(flie, ['xlsx'])"
          :on-change="importFile"
          :show-file-list="false"
          :accept="['.xlsx'].join(',')"
          action="https://httpbin.org/post"
        >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">
            将文件拖到此处，或<em>点击上传</em>,仅支持xlsx格式
          </div>
        </el-upload>
        <Show-List v-else :item.sync="form.dataFile"> </Show-List>
      </el-form-item>
    </el-form>
    <el-button @click="exportExcel">生成</el-button>
  </div>
</template>

<script>
import JSZip from "jszip";
import ShowList from "./components/ShowList";
import { saveAs } from "file-saver";
import dayjs from "dayjs";
import XlsxTemplate from "xlsx-template";
import Docxtemplater from "docxtemplater";
import JSZipUtils from "jszip-utils";
import XLSX from "xlsx";
import PizZip from "pizzip";
export default {
  name: "App",
  data() {
    return {
      rules: {
        templateFile: [{ required: true }],
        sheetNumber: [{ required: true }],
        dataFile: [{ required: true }],
      },
      form: { templateFile: null, dataFile: null, sheetNumber: null },
      loading: null,
      template: null,
      templateUrl: null,
      results: [],
      options: [],
    };
  },

  mounted() {},

  components: { ShowList },

  methods: {
    beforeUpload(file, previewList) {
      const aa = file.name.split(".");
      let hz = aa[aa.length - 1].toLowerCase();
      const canPreview = previewList.includes(hz);
      const isLt2M = file.size / 1024 / 1024 < 2;
      if (!isLt2M) {
        this.$message.error("文件大小不能超过2M!");
      }
      if (!canPreview) {
        this.$message.error("格式错误");
      }
      // if (canPreview && isLt2M) {
      //   this.templateFile = file;
      // }
      //   this.loading = this.$loading({ background: "rgba(0, 0, 0, 0.7)" });
      return canPreview && isLt2M;
    },
    handleAvatarSuccess(file) {
      const aa = file.name.split(".");
      let hz = aa[aa.length - 1].toLowerCase();
      this.form.templateFile = file.raw;
      this.templateUrl = window.URL.createObjectURL(file.raw);
      JSZipUtils.getBinaryContent(this.templateUrl, (err, data) => {
        //this.loading.close();
        if (hz === "xlsx") {
          this.options = new XlsxTemplate(data).sheets;
        } else {
          this.options = [];
        }
      });
    },
    importFile(file) {
      // this.loading.close();
      this.form.dataFile = file.raw;
      const _this = this;
      let reader = new FileReader();
      FileReader.prototype.readAsBinaryString = function (f) {
        let reader = new FileReader();

        reader.onload = (e) => {
          const data = e.target.result;
          const workbook = XLSX.read(data, { type: "array" });
          const firstSheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[firstSheetName];
          // const header = _this.getHeaderRow(worksheet)
          _this.results = XLSX.utils.sheet_to_json(worksheet);
        };
        reader.readAsArrayBuffer(f);
      };

      reader.readAsBinaryString(file.raw);
    },
    createAXlsxFile(zip, index) {
      return new Promise((resolve, reject) => {
        JSZipUtils.getBinaryContent(this.templateUrl, (err, data) => {
          const template = new XlsxTemplate(data);
          const regex = /\$\((.*?)\)/g;
          Object.keys(this.results[index]).forEach((key) => {
            const match = regex.exec(key);
            if (match) {
              this.results[index][key] = dayjs(this.results[index][key]).format(
                match[1]
              );
            }
          });
          console.log(this.results[index]);
          template.substitute(this.form.sheetNumber, this.results[index]);

          // Get binary data
          let templateData = template.generate({ type: "blob" });

          zip.file(
            index + 1 + "." + this.form.templateFile.name,
            templateData,
            { binary: true }
          );
          resolve();
        });
      });
    },
    createADocXFile(zip, index) {
      return new Promise((resolve, reject) => {
        JSZipUtils.getBinaryContent(this.templateUrl, (err, data) => {
          // 设定占位符，默认为{}
          let options = {
            delimiters: {
              start: "${",
              end: "}",
            },
          };
          const pzip = new PizZip(data);
          const doc = new Docxtemplater().loadZip(pzip).setOptions(options);
          const regex = /\$\((.*?)\)/g
          Object.keys(this.results[index]).forEach((key) => {
            const match = regex.exec(key);
            if (match) {
              this.results[index][key] = dayjs(this.results[index][key]).format(
                match[1]
              );
            }
          });
          // 替换占位符
          doc.setData(this.results[index]);
          doc.render();

          let templateData = doc.getZip().generate({
            type: "blob",
          });
          zip.file(
            index + 1 + "." + this.form.templateFile.name,
            templateData,
            { binary: true }
          );
          resolve();
        });
      });
    },
    async exportExcel() {
      this.$refs.form
        .validate()
        .then(async () => {
          var zip = new JSZip();
          const promises = [];
          const aa = this.form.templateFile.name.split(".");
          let hz = aa[aa.length - 1].toLowerCase();
          for (let index = 0; index < this.results.length; index++) {
            if (hz == "docx") {
              promises.push(this.createADocXFile(zip, index));
            } else if (hz == "xlsx") {
              promises.push(this.createAXlsxFile(zip, index));
            }
          }
          Promise.all(promises).then(() => {
            zip.generateAsync({ type: "blob" }).then((content) => {
              // 生成二进制流
              saveAs(content, `下班.zip`);
            });
          });
        })
        .catch((err) => {
          console.log(err);
        });
    },
  },

  // props: {
  //   params: {
  //     type: Object,
  //     default() {
  //       return {}
  //     },
  //   },
  // },
};
</script>
<style lang="scss" scoped></style>
